/**
 * 
 */
package t4j.concurrency;

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

class CharQueue extends LinkedBlockingQueue<Character>{}

class Sender2 implements Runnable {

	private Random rand = new Random(47);
	private CharQueue out = new CharQueue(); 
	
	public CharQueue getCharQueue(){return out;}
	
	@Override
	public void run() {
		try {
			while (true)
				for (char c = 'A'; c <= 'z'; c++) {
					out.put(c);
					TimeUnit.MILLISECONDS.sleep(rand.nextInt(500));
				}
		} catch (InterruptedException e) {
			System.out.println(e + " Sender interrupted");
		}
		
	}
	
}

class Receiver2 implements Runnable {

	private CharQueue in;

	public Receiver2(Sender2 sender) throws IOException {
		in = sender.getCharQueue();
	}

	@Override
	public void run() {
		try {
			while (true) {
				//如果调用read()时，没有数据，管道将自动阻塞
				System.out.println("Read " + (char) in.take() + ", ");//注意:这里read()是可中断的，如果改为System.in.read()就不能中断了
			}
		}catch (InterruptedException e) {
			System.out.println(e + " Receiver interrupted");
		}
	}
	
}

public class E30_PipedIO {
	public static void main(String[] args) throws Exception {
		Sender2 sender = new Sender2();
		Receiver2 receiver = new Receiver2(sender);
		
		ExecutorService exec = Executors.newCachedThreadPool();
		exec.execute(sender);
		exec.execute(receiver);
		
		TimeUnit.SECONDS.sleep(4);
		exec.shutdownNow();
	}
}
